from typing import List, Optional
from sqlalchemy.orm import Session
from sqlalchemy import and_

from app.models.article import Article
from app.models.tag import Tag
from app.schemas.article import ArticleCreate, ArticleUpdate

def get_article(db: Session, article_id: int) -> Optional[Article]:
    """获取单篇文章（包括关联的标签）"""
    return db.query(Article).filter(
        and_(
            Article.id == article_id,
            Article.is_deleted == False
        )
    ).first()

def get_articles(
    db: Session,
    skip: int = 0,
    limit: int = 10,
    status: Optional[str] = None
) -> List[Article]:
    """获取文章列表（包括关联的标签）"""
    query = db.query(Article).filter(Article.is_deleted == False)
    if status:
        query = query.filter(Article.status == status)
    return query.offset(skip).limit(limit).all()

def create_article(db: Session, article: ArticleCreate, author_id: int = 1) -> Article:
    """创建新文章并关联标签"""
    # 1. 创建文章基本信息（不包含tags字段）
    article_data = article.model_dump(exclude={"tags"})
    db_article = Article(**article_data, author_id=author_id)
    
    # 2. 保存文章
    db.add(db_article)
    db.commit()
    db.refresh(db_article)
    
    # 3. 关联标签
    if article.tags:
        tags = db.query(Tag).filter(Tag.id.in_(article.tags)).all()
        db_article.tags = tags
        
        # 更新标签使用次数
        for tag in tags:
            tag.usage_count += 1
        
        db.commit()
        db.refresh(db_article)
    
    return db_article

def update_article(
    db: Session,
    article_id: int,
    article: ArticleUpdate
) -> Optional[Article]:
    """更新文章及其关联的标签"""
    # 1. 查找文章
    db_article = get_article(db, article_id)
    if not db_article:
        return None
    
    # 2. 更新基础字段
    update_data = article.model_dump(exclude={"tags"}, exclude_unset=True)
    for field, value in update_data.items():
        setattr(db_article, field, value)
    
    # 3. 如果传入了标签ID，更新标签关联
    if article.tags is not None:
        # 先减少原标签的使用次数
        for old_tag in db_article.tags:
            old_tag.usage_count -= 1
        
        # 关联新标签
        new_tags = db.query(Tag).filter(Tag.id.in_(article.tags)).all()
        db_article.tags = new_tags
        
        # 更新新标签的使用次数
        for tag in new_tags:
            tag.usage_count += 1
    
    db.commit()
    db.refresh(db_article)
    return db_article

def delete_article(db: Session, article_id: int) -> bool:
    """删除文章（软删除）并更新标签使用次数"""
    db_article = get_article(db, article_id)
    if not db_article:
        return False
    
    # 减少标签的使用次数
    for tag in db_article.tags:
        tag.usage_count -= 1
    
    # 软删除文章
    db_article.is_deleted = True
    db.commit()
    return True

def increment_view_count(db: Session, article_id: int) -> Optional[Article]:
    """增加文章浏览次数"""
    db_article = get_article(db, article_id)
    if not db_article:
        return None
    
    db_article.view_count += 1
    db.commit()
    db.refresh(db_article)
    return db_article 